package com.gitee.l0km.xthrift.thrift.protocol;

import org.apache.thrift.protocol.TField;
import org.apache.thrift.protocol.TProtocol;
import org.apache.thrift.protocol.TType;

import com.facebook.swift.codec.ThriftCodec;
import com.facebook.swift.codec.internal.TProtocolWriter;
import com.facebook.swift.codec.internal.builtin.StringThriftCodec;

/**
 * @author guyadong
 * @since 1.5.0
 */
public class TProtocolWriterXthrift extends TProtocolWriter {
	protected final TProtocol protocol;
	private static final ThriftCodec<String> STRIN_CODEC = new StringThriftCodec();
	private TProtocolWriterXthrift(TProtocol protocol) {
		super(protocol);
		this.protocol = protocol;
	}

	@SuppressWarnings("rawtypes")
	private <T> boolean writeEnumIfJsons(String name, short id,T enumValue) throws Exception {
		TJSONProtocolXthrift _protocol = TProtocolSupport.fetchJSONXthrift(protocol);
        if((enumValue instanceof Enum) && null != _protocol && _protocol.enumValueAsString()) {
        	_protocol.writeFieldBegin(new TField(name, TType.STRING, id));
        	STRIN_CODEC.write(((Enum) enumValue).name(), _protocol);
        	_protocol.writeFieldEnd();
        	return true;
        }
        return false;
	}
	@Override
	public <T> void writeField(String name, short id, ThriftCodec<T> codec, T value) throws Exception {
        if(!writeEnumIfJsons(name, id, value)) {
        	super.writeField(name, id, codec, value);
        }
	}

	@Override
	public <T extends Enum<T>> void writeEnumField(String name, short id, ThriftCodec<T> codec, T enumValue)
			throws Exception {
		if(!writeEnumIfJsons(name, id, enumValue)) {
			super.writeEnumField(name, id, codec, enumValue);
		}
	}

	public static TProtocolWriter of(TProtocol protocol) {
		if (TProtocolSupport.isJSONXthrift(protocol)) {
			return new TProtocolWriterXthrift(protocol);
		}
		return new TProtocolWriter(protocol);
	}
}
